home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
boe.pres.k12.wv.us
/
boe.pres.k12.wv.us.zip
/
boe.pres.k12.wv.us
/
Utilities
/
Xerox Workcentre 5335
/
Windows Scan
/
64-bit_x64
/
Japanese
/
cpsimage.cab
/
data
/
sys
/
XmlWriter.elf
< prev
next >
Wrap
Text File
|
2009-04-23
|
34KB
|
991 lines
#load "sys/collections.elf";
/*****************************************************************************/
/*
** This script contains a set of classes for the dynamic generation of a
** well-formed XML document. The classes provide the means to incrementally
** build and write a formatted or unformatted XML document to a file or a
** string via an XmlWriter instance.
**
** An XmlWriter instance is created using the XmlWriterFactory class. The
** XmlWriterFactory.createFileWriter method can be used to create a writer for
** writing XML data to a file. The XmlWriterFactory.createStringWriter method
** can be used to create a writer for writing XML data to a string.
*/
/*****************************************************************************/
CLASS Xml {
STRING XmlNamespaceUri = "http://www.w3.org/XML/1998/namespace";
STRING XmlnsNamespaceUri = "http://www.w3.org/2000/xmlns/";
}
CLASS XmlSpace {
INTEGER None = 0;
INTEGER Default = 1;
INTEGER Preserve = 2;
}
/*****************************************************************************/
/*
** This class is the abstract base class for state objects representing the
** current state of an XmlWriter instance.
*/
/* @writeDocumentStart Writes the XML declaration. */
/* @writeDocumentEnd Writes end tags for any open XML elements or attributes and puts the writer in the End state. */
/* @writeElementStart Writes specified XML element start tag. */
/* @writeElementEnd Writes end tag for the last XML element started with 'writeElementStart' call. */
/* @writeString Writes the given XML text content. */
/* @writeAttributeStart Writes the start of an XML attribute. */
/* @writeAttributeEnd Writes the end for last XML attribute started with 'writeAttributeStart' call. */
/* @writeComment Writes an XML comment containing specified text. */
/* @writeRaw Writes raw XML data from a string (with no validation). */
/*****************************************************************************/
private CLASS XmlWriterState {
// Public Methods
METHOD writeDocumentStart (XmlWriter writer, STRING encoding) {
}
METHOD writeDocumentEnd (XmlWriter writer) {
}
METHOD writeElementStart (XmlWriter writer, STRING prefix,
STRING localName, STRING ns) {
}
METHOD writeElementEnd (XmlWriter writer) {
}
METHOD writeString (XmlWriter writer, STRING text) {
}
METHOD writeAttributeStart (XmlWriter writer, STRING prefix,
STRING localName, STRING ns) {
}
METHOD writeAttributeEnd (XmlWriter writer) {
}
METHOD writeComment (XmlWriter writer, STRING text) {
}
METHOD writeRaw (XmlWriter writer, STRING xmlstr) {
}
}
/*****************************************************************************/
/*
** This class is the XmlWriterState representing the initial state of an
** XmlWriter instance in which no XML data has been written.
*/
/****************************************************************************/
private CLASS XmlStartWriterState EXTENDS XmlWriterState {
// Public Methods
METHOD writeDocumentStart (XmlWriter writer, STRING encoding) {
if (!encoding)
encoding = "utf-8";
STRING prolog = "<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>";
writer.write (str: prolog);
writer.setState (state: XmlWriter.prologWriterState);
}
METHOD writeDocumentEnd (XmlWriter writer) {
print "InvalidOperationException: No root element present";
}
METHOD writeElementStart (XmlWriter writer, STRING prefix,
STRING localName, STRING ns) {
writer.writeElementStartInternal (prefix: prefix,
localName: localName, ns: ns);
writer.setState (state: XmlWriter.elementWriterState);
}
METHOD writeElementEnd (XmlWriter writer) {
print "InvalidOperationException: No root element present";
}
METHOD writeString (XmlWriter writer, STRING text) {
print "InvalidOperationException: No root element present";
}
METHOD writeAttributeStart (XmlWriter writer, STRING prefix,
STRING localName, STRING ns) {
print "InvalidOperationException: Cannot write attribute start outside element start";
}
METHOD writeAttributeEnd (XmlWriter writer) {
print "InvalidOperationException: Cannot write attribute end outside element start";
}
METHOD writeComment (XmlWriter writer, STRING text) {
writer.write (str: "<!-- ");
writer.write (str: text);
writer.write (str: " -->");
}
METHOD writeRaw (XmlWriter writer, STRING xmlstr) {
writer.write (str: xmlstr);
writer.setState (state: XmlWriter.endWriterState);
}
}
/*****************************************************************************/
/*
** This class is the XmlWriterState representing the state of an XmlWriter
** instance in which the XML prolog has been written.
*/
/****************************************************************************/
private CLASS XmlPrologWriterState EXTENDS XmlWriterState {
// Public Methods
METHOD writeDocumentStart (XmlWriter writer, STRING encoding) {
print "InvalidOperationException: Cannot have more than one XML declaration";
}
METHOD writeDocumentEnd (XmlWriter writer) {
print "InvalidOperationException: No root element present";
}
METHOD writeElementStart (XmlWriter writer, STRING prefix,
STRING localName, STRING ns) {
writer.newlineAndIndent ();
writer.writeElementStartInternal (prefix: prefix,
localName: localName, ns: ns);
writer.setState (state: XmlWriter.elementWriterState);
}
METHOD writeElementEnd (XmlWriter writer) {
print "InvalidOperationException: No root element present";
}
METHOD writeString (XmlWriter writer, STRING text) {
print "InvalidOperationException: No root element present";
}
METHOD writeAttributeStart (XmlWriter writer, STRING prefix,
STRING localName, STRING ns) {
print "Cannot write attribute start outside element start";
}
METHOD writeAttributeEnd (XmlWriter writer) {
print "Cannot write attribute end outside element start";
}
METHOD writeComment (XmlWriter writer, STRING text) {
writer.newlineAndIndent ();
writer.write (str: "<!-- ");
writer.write (str: text);
writer.write (str: " -->");
}
METHOD writeRaw (XmlWriter writer, STRING xmlstr) {
writer.write (str: "\n");
writer.write (str: xmlstr);
writer.setState (state: XmlWriter.endWriterState);
}
}
/*****************************************************************************/
/*
** This class is the XmlWriterState representing the state of an XmlWriter
** instance in which an XML element start tag is being written.
*/
/****************************************************************************/
private CLASS XmlElementWriterState EXTENDS XmlWriterState {
// Public Methods
METHOD writeDocumentStart (XmlWriter writer, STRING encoding) {
print "InvalidOperationException: Cannot write XML declaration inside element";
}
METHOD writeDocumentEnd (XmlWriter writer) {
BOOLEAN done;
for (done = FALSE; done; ) {
if (writer.openElems.isEmpty ())
done = TRUE;
else
this.writeElementEnd (writer: writer);
}
writer.setState (state: XmlWriter.endWriterState);
}
METHOD writeElementStart (XmlWriter writer, STRING prefix,
STRING localName, STRING ns) {
writer.writeNamespaces ();
writer.write (str: ">");
writer.newlineAndIndent ();
writer.writeElementStartInternal (prefix: prefix,
localName: localName, ns: ns);
}
METHOD writeElementEnd (XmlWriter writer) {
writer.writeNamespaces ();
writer.write (str: "/>");
writer.openElems.pop ();
writer.setState (state: XmlWriter.contentWriterState);
}
METHOD writeString (XmlWriter writer, STRING text) {
writer.writeNamespaces ();
writer.write (str: ">");
writer.setState (state: XmlWriter.contentWriterState);
writer.currentState.writeString (writer: writer, text: text);
}
METHOD writeAttributeStart (XmlWriter writer, STRING prefix,
STRING localName, STRING ns) {
XmlOpenElement elem = writer.openElems.peek ();
if (prefix == "xml") {
ns = Xml.XmlNamespaceUri;
if (localName == "lang")
elem.openXmlLang = TRUE;
else if (localName == "space")
elem.openXmlSpace = TRUE;
}
if ((prefix.length () > 0) && (ns.length () == 0)) {
if (prefix != "xmlns") {
print "ArgumentException: Cannot use prefix <" + prefix +
"> with empty namespace";
return;
}
}
if (prefix == "xmlns") {
if (localName.length () == 0) {
localName = prefix;
prefix = "";
}
}
if ((prefix == "xmlns" || localName == "xmlns") &&
(ns && (ns != Xml.XmlnsNamespaceUri))) {
print "ArgumentException: xmlns prefix is bound to namespace" +
Xml.XmlnsNamespaceUri;
return;
}
if (ns == Xml.XmlnsNamespaceUri) {
prefix = "";
if (localName != "xmlns")
prefix = "xmlns";
}
if (ns && prefix != "xmlns") {
STRING existingPrefix = elem.lookupPrefix (ns: ns);
if (existingPrefix == "") {
if ((prefix == "") || elem.lookupNamespace (prefix: prefix))
prefix = elem.generatePrefix ();
}
if ((prefix == "") && (ns != Xml.XmlnsNamespaceUri))
prefix = existingPrefix;
}
STRING qName = localName;
if (prefix.length () != 0)
qName = prefix + ":" + qName;
writer.writeAttributeIndent ();
writer.write (str: qName);
writer.write (str: "=\"");
writer.setState (state: XmlWriter.attributeWriterState);
}
METHOD writeAttributeEnd (XmlWriter writer) {
print "InvalidOperationException: Cannot write attribute end outside element start";
}
METHOD writeComment (XmlWriter writer, STRING text) {
writer.writeNamespaces ();
writer.write (str: ">");
writer.setState (state: XmlWriter.contentWriterState);
writer.currentState.writeComment (writer: writer, text: text);
}
METHOD writeRaw (XmlWriter writer, STRING xmlstr) {
writer.writeNamespaces ();
writer.write (str: ">");
writer.write (str: "\n");
writer.write (str: xmlstr);
writer.setState (state: XmlWriter.contentWriterState);
}
}
/*****************************************************************************/
/*
** This class is the XmlWriterState representing the state of an XmlWriter
** instance in which XML element content is being written.
*/
/****************************************************************************/
private CLASS XmlContentWriterState EXTENDS XmlWriterState {
// Public Methods
METHOD writeDocumentStart (XmlWriter writer, STRING encoding) {
print "InvalidOperationException: Cannot write XML declaration inside element";
}
METHOD writeDocumentEnd (XmlWriter writer) {
BOOLEAN done;
for (done = FALSE; done; ) {
if (writer.openElems.isEmpty ())
done = TRUE;
else
this.writeElementEnd (writer: writer);
}
writer.setState (state: XmlWriter.endWriterState);
}
METHOD writeElementStart (XmlWriter writer, STRING prefix,
STRING localName, STRING ns) {
writer.newlineAndIndent ();
writer.writeElementStartInternal (prefix: prefix,
localName: localName, ns: ns);
writer.setState (state: XmlWriter.elementWriterState);
}
METHOD writeElementEnd (XmlWriter writer) {
XmlOpenElement elem = writer.openElems.pop ();
if (elem.childCount)
writer.newlineAndIndent ();
writer.write (str: "</");
writer.write (str: elem.qName);
writer.write (str: ">");
}
METHOD writeString (XmlWriter writer, STRING text) {
writer.write (str: writer.convertString (str: text));
}
METHOD writeAttributeStart (XmlWriter writer, STRING prefix,
STRING localName, STRING ns) {
print "InvalidOperationException: Cannot write attribute start outside element start";
}
METHOD writeAttributeEnd (XmlWriter writer) {
print "InvalidOperationException: Cannot write attribute end outside element start";
}
METHOD writeComment (XmlWriter writer, STRING text) {
writer.newlineAndIndent ();
writer.write (str: "<!-- ");
writer.write (str: text);
writer.write (str: " -->");
}
METHOD writeRaw (XmlWriter writer, STRING xmlstr) {
writer.newlineAndIndent ();
writer.write (str: xmlstr);
writer.setState (state: XmlWriter.elementWriterState);
}
}
/*****************************************************************************/
/*
** This class is the XmlWriterState representing the state of an XmlWriter
** instance in which XML attribute value is being written.
*/
/****************************************************************************/
private CLASS XmlAttributeWriterState EXTENDS XmlWriterState {
// Public Methods
METHOD writeDocumentStart (XmlWriter writer, STRING encoding) {
print "InvalidOperationException: Cannot write XML declaration inside attribute";
}
METHOD writeDocumentEnd (XmlWriter writer) {
this.writeAttributeEnd (writer: writer);
this.writer.currentState.writeDocumentEnd (writer: writer);
}
METHOD writeElementStart (XmlWriter writer, STRING prefix,
STRING localName, STRING ns) {
print "InvalidOperationException: Cannot write element start inside attribute";
}
METHOD writeElementEnd (XmlWriter writer) {
print "InvalidOperationException: Cannot write element end inside attribute";
}
METHOD writeString (XmlWriter writer, STRING text) {
text = writer.convertString (str: text);
XmlOpenElement elem = writer.openElems.peek ();
if (!elem.openXmlLang && !elem.openXmlSpace)
writer.write (str: text);
else {
if (elem.openXmlLang)
elem.xmlLang = text;
else {
if (text == "default")
elem.xmlSpace = XmlSpace.Default;
else if (text == "preserve")
elem.xmlSpace = XmlSpace.Preserve;
else {
print "ArgumentException: Invalid xml:space value <" +
text + ">";
return;
}
}
}
}
METHOD writeAttributeStart (XmlWriter writer, STRING prefix,
STRING localName, STRING ns) {
print "InvalidOperationException: Cannot write attribute start inside attribute";
}
METHOD writeAttributeEnd (XmlWriter writer) {
XmlOpenElement elem = writer.openElems.peek ();
if (elem.openXmlLang) {
writer.write (str: elem.xmlLang);
elem.openXmlLang = FALSE;
}
if (elem.openXmlSpace) {
if (elem.xmlSpace == XmlSpace.Preserve)
writer.write (str: "preserve");
else if (elem.xmlSpace == XmlSpace.Default)
writer.write (str: "default");
elem.openXmlSpace = TRUE;
}
writer.write (str: "\"");
writer.setState (state: XmlWriter.elementWriterState);
}
METHOD writeComment (XmlWriter writer, STRING text) {
print "InvalidOperationException: Cannot write comment inside atribute";
}
METHOD writeRaw (XmlWriter writer, STRING xmlstr) {
print "InvalidOperationException: Cannot write raw XML inside attribute";
}
}
/*****************************************************************************/
/*
** This class is the XmlWriterState representing the final state of an
** XmlWriter instance in which XML data has been written.
*/
/****************************************************************************/
private CLASS XmlEndWriterState EXTENDS XmlWriterState {
// Public Methods
METHOD writeDocumentStart (XmlWriter writer, STRING encoding) {
print "InvalidOperationException: Cannot write XML declaration after root element end";
}
METHOD writeDocumentEnd (XmlWriter writer) {
print "InvalidOperationException: Cannot write document end after root element end";
}
METHOD writeElementStart (XmlWriter writer, STRING prefix,
STRING localName, STRING ns) {
print "InvalidOperationException: Cannot write element start after root element end";
}
METHOD writeElementEnd (XmlWriter writer) {
print "InvalidOperationException: Cannot write element end after root element end";
}
METHOD writeString (XmlWriter writer, STRING text) {
print "InvalidOperationException: Cannot write string content after root element end";
}
METHOD writeAttributeStart (XmlWriter writer, STRING prefix,
STRING localName, STRING ns) {
print "InvalidOperationException: Cannot write attribute start after root element end";
}
METHOD writeAttributeEnd (XmlWriter writer) {
print "InvalidOperationException: Cannot write attribute end after root element end";
}
METHOD writeComment (XmlWriter writer, STRING text) {
writer.newlineAndIndent ();
writer.write (str: "<!-- ");
writer.write (str: text);
writer.write (str: " -->");
}
METHOD writeRaw (XmlWriter writer, STRING xmlstr) {
print "InvalidOperationException: Cannot write raw XML after root element end";
}
}
/*****************************************************************************/
/*
** This class represents an XML character entity.
*/
/****************************************************************************/
private CLASS XmlCharEntity {
// Fields
STRING name;
STRING character;
}
/*****************************************************************************/
/*
** This class represents an XML namespace.
*/
/****************************************************************************/
private CLASS XmlNamespace {
// Fields
STRING prefix;
STRING ns;
}
/*****************************************************************************/
/*
** This class implements an open XML element.
*/
/* @addNamespace Adds a namespace to the open XML element. */
/* @generatePrefix Generates new prefix for undeclared namespace. */
/* @lookupPrefix Returns the closest prefix defined in the current namespace scope for the given namespace. */
/* @lookupNamespace Returns the namespace corresponding to given prefix */
/****************************************************************************/
private CLASS XmlOpenElement {
// Fields
STRING qName;
STRING defaultNs;
INTEGER childCount;
LIST namespaces;
XmlOpenElement parent;
STRING xmlLang;
BOOLEAN openXmlLang = FALSE;
BOOLEAN openXmlSpace = FALSE;
INTEGER xmlSpace = XmlSpace.None;
INTEGER genPrefixIndex = 0;
// Public Methods
METHOD addNamespace (STRING prefix, STRING ns) {
if (!ns) {
print "ArgumentNullException: No namespace specified";
return;
}
if ((prefix == "xml") && (ns != Xml.XmlNamespaceUri)) {
print "ArgumentException: xml prefix must be bound to URI <" +
Xml.XmlNamespaceUri + ">";
return;
}
else if (prefix == "xmlns") {
print "ArgumentException: prefix cannot be \"xmlns\"";
return;
}
else if (ns == Xml.XmlnsNamespaceUri) {
print "ArgumentException: URI <" + Xml.XmlnsNamespaceUri +
"> cannot be declared for any namespace";
return;
}
if (prefix == "") {
this.defaultNs = ns;
}
else {
INTEGER i;
for (i = 0; i < this.namespaces.length (); i++) {
if (this.namespaces[i].ns == ns) {
break;
}
}
if (i < this.namespaces.length ())
this.namespaces[i].prefix = prefix;
else {
XmlNamespace item = new (XmlNamespace, ns: ns, prefix: prefix);
this.namespaces.insert (obj: item);
}
}
}
METHOD lookupPrefix (STRING ns) RETURNS (STRING prefix) {
if (!ns || ns == "") {
print "ArgumentNullException: Namespace cannot be empty";
prefix = "";
return;
}
INTEGER i;
for (i = 0; i < this.namespaces.length (); i++) {
if (this.namespaces[i].ns == ns) {
break;
}
}
if (i < this.namespaces.length ())
prefix = this.namespaces[i].prefix;
}
METHOD lookupNamespace (STRING prefix) RETURNS (STRING ns) {
if (!prefix || prefix == "")
ns = this.defaultNs;
else {
INTEGER i;
for (i = 0; i < this.namespaces.length (); i++) {
if (this.namespaces[i].prefix == prefix) {
break;
}
}
if (i < this.namespaces.length ())
ns = this.namespaces[i].ns;
}
}
METHOD generatePrefix (STRING ns) RETURNS (STRING prefix) {
STRING p;
BOOLEAN done = FALSE;
for (!done;) {
++this.genPrefixIndex;
p = "ns" + this.genPrefixIndex;
if (!this.lookupNamespace (prefix: p)) {
this.addNamespace (prefix: p, ns: ns);
done = TRUE;
}
}
}
}
/*****************************************************************************/
/*
** This class implements a text buffer for holding unformatted XML data.
*/
/* @create creates an XmlBuffer instance for unformatted XML data or an XmlFormattedBuffer for formatted XML data. */
/* @lookupPrefix Returns the closest prefix defined in the current namespace scope for the given namespace. */
/* @append Appends given string to text buffer. */
/* @clear Clears text buffer. */
/* @canAppend Returns TRUE if given string can be appended to text buffer without exceeding buffer capacity; FALSE otherwise. */
/* @toString Returns a copy of the text buffer. */
/* @newlineAndIndent Appends newline and indentation to text buffer. */
/****************************************************************************/
private CLASS XmlBuffer {
// Constants
INTEGER CAPACITY = 512;
INTEGER DEFAULT_INDENT_SIZE = 2;
// Fields
STRING xmlStr = "";
// Public Methods
METHOD create (BOOLEAN indent, INTEGER indentSize) RETURNS (XmlBuffer buf) {
if (indent) {
XmlFormattedBuffer fbuf = new (XmlFormattedBuffer);
if (!indentSize)
indentSize = XmlBuffer.DEFAULT_INDENT_SIZE;
INTEGER i;
for (i = 0; i < indentSize; i++)
fbuf.indentStr = fbuf.indentStr + " ";
buf = fbuf;
}
else {
buf = new (XmlBuffer);
}
}
METHOD append (STRING str) {
this.xmlStr = this.xmlStr + str;
}
METHOD clear () {
this.xmlStr = "";
}
METHOD canAppend (STRING str) RETURNS (BOOLEAN result) {
if (!str)
result = FALSE;
else
result = (this.xmlStr.length () + str.length () >= XmlBuffer.CAPACITY);
}
METHOD toString () RETURNS (STRING str) {
str = this.xmlStr.Copy ();
}
METHOD writeAttributeIndent (INTEGER level) {
this.xmlStr = this.xmlStr + " ";
}
METHOD newlineAndIndent (INTEGER level) {
}
}
/*****************************************************************************/
/*
** This class implements a text buffer for holding formatted XML data.
*/
/****************************************************************************/
private CLASS XmlFormattedBuffer EXTENDS XmlBuffer {
// Fields
STRING indentStr;
// Public Methods
METHOD writeAttributeIndent (INTEGER level) {
this.newlineAndIndent (level: level);
}
METHOD newlineAndIndent (INTEGER level) {
this.append (str: "\n");
INTEGER i;
for (i = 0; i < level; i++)
this.append (str: this.indentStr);
}
}
/*****************************************************************************/
/*
** This class is the abstract base class of a writer for the generation of XML data.
*/
/* @setState Sets the state of XMLWriter instance. */
/* @writeDocumentStart Writes the XML declaration. */
/* @writeDocumentEnd Writes end tags for any open XML elements or attributes and puts the writer in the End state. */
/* @writeElementStart Writes specified XML element start tag. */
/* @writeElementEnd Writes end tag for the last XML element started with 'writeElementStart' call. */
/* @writeString Writes the given XML text content. */
/* @writeAttributeStart Writes the start of an XML attribute. */
/* @writeAttributeEnd Writes the end for last XML attribute started with 'writeAttributeStart' call. */
/* @writeComment Writes an XML comment containing specified text. */
/* @writeRaw Writes raw XML data from a string (with no validation). */
/* @writeAttributeIndent Writes indentation for an XML attribute. */
/* @newlineAndIndent Writes new line and indentation. */
/* @convertString Replaces special character entities with escaped forms. */
/* @flush Flushes the data stream. */
/* @write Writes string to internal buffer. */
/* @writeNamespaces Writes XML attributes for namespaces of an open Element. */
/* @writeElementStartInternal Writes data for specified XML element start tag. */
/****************************************************************************/
CLASS XmlWriter {
// WriterState Constants
XmlAttributeWriterState attributeWriterState;
XmlContentWriterState contentWriterState;
XmlElementWriterState elementWriterState;
XmlPrologWriterState prologWriterState;
XmlStartWriterState startWriterState;
XmlEndWriterState endWriterState;
// Fields
XmlWriterState currentState;
XmlBuffer xmlBuf;
STACK openElems;
// Public Methods
METHOD setState (XmlWriterState state) {
this.currentState = state;
}
METHOD writeDocumentStart (STRING encoding) {
this.currentState.writeDocumentStart (writer: this, encoding: encoding);
}
METHOD writeDocumentEnd () {
this.currentState.writeDocumentEnd (writer: this);
}
METHOD writeElementStart (STRING prefix, STRING localName, STRING ns) {
this.currentState.writeElementStart (writer: this, prefix: prefix,
localName: localName, ns: ns);
}
METHOD writeElementEnd () {
this.currentState.writeElementEnd (writer: this);
}
METHOD writeElementString (STRING prefix, STRING localName,
STRING ns, STRING text) {
this.writeElementStart (prefix: prefix, localName: localName, ns: ns);
this.writeString (text: text);
this.writeElementEnd ();
}
METHOD writeString (STRING text) {
this.currentState.writeString (writer: this, text: text);
}
METHOD writeAttributeStart (STRING prefix, STRING localName, STRING ns) {
this.currentState.writeAttributeStart (writer: this, prefix: prefix,
localName: localName, ns: ns);
}
METHOD writeAttributeEnd () {
this.currentState.writeAttributeEnd (writer: this);
}
METHOD writeAttributeString (STRING prefix, STRING localName,
STRING ns, STRING text) {
this.writeAttributeStart (prefix: prefix, localName: localName, ns: ns);
this.writeString (text: text);
this.writeAttributeEnd ();
}
METHOD writeComment (STRING text) {
this.currentState.writeComment (writer: this, text: text);
}
METHOD writeRaw (XmlWriter writer, STRING xmlstr) {
this.currentState.writeRaw (writer: this, xmlstr: xmlstr);
}
METHOD writeAttributeIndent () {
this.xmlBuf.writeAttributeIndent (level: this.openElems.getCount ());
}
METHOD newlineAndIndent () {
this.xmlBuf.newlineAndIndent (level: this.openElems.getCount ());
}
METHOD convertString (STRING str) RETURNS (STRING newStr) {
if (!str) {
newStr = "";
return ;
}
LIST entities = (new (XmlCharEntity, name: "amp", character: "&"),
new (XmlCharEntity, name: "lt", character: "<"),
new (XmlCharEntity, name: "gt", character: ">"),
new (XmlCharEntity, name: "apos", character: "\'"),
new (XmlCharEntity, name: "quot", character: "\""));
LIST substr;
INTEGER i;
newStr = str;
foreach (entities: entity) {
substr = newStr.split (delims: entity.character);
for (i = 1; i < substr.length (); i++)
substr[0] = substr[0] + "&" + entity.name + ";" + substr[i];
newStr = substr[0];
}
}
METHOD flush () {
}
// Protected Methods
METHOD write (STRING str) {
}
METHOD writeNamespaces () {
if (!this.openElems.isEmpty ()) {
XmlOpenElement elem = this.openElems.peek ();
STRING ns, prefix;
foreach (elem.namespaces: entry) {
ns = entry.ns;
prefix = entry.prefix;
this.writeAttributeIndent ();
this.write (str: "xmlns:" + prefix + "=\"" + ns + "\"");
}
if (elem.defaultNs != "") {
if (!elem.parent || (elem.defaultNs != elem.parent.defaultNs)) {
this.writeAttributeIndent ();
this.write (str: "xmlns=\"" + elem.defaultNs + "\"");
}
}
}
}
METHOD writeElementStartInternal (STRING prefix,
STRING localName, STRING ns) {
STRING qName = localName;
if (prefix && prefix.length () != 0)
qName = prefix + ":" + qName;
XmlOpenElement parent;
if (!this.openElems.isEmpty ()) {
parent = this.openElems.peek ();
parent.childCount++;
}
XmlOpenElement openElem = new (XmlOpenElement, qName: qName,
childCount: 0, parent: parent);
if (ns)
openElem.addNamespace (prefix: prefix, ns: ns);
this.openElems.push (item: openElem);
this.write (str: "<");
this.write (str: qName);
}
}
/*****************************************************************************/
/*
** This class implements a writer for generating and writing XML data to a
** string.
*/
/* @reset Clears text buffer. */
/* @toString Returns text buffer contents. */
/*****************************************************************************/
CLASS XmlStringWriter EXTENDS XmlWriter {
// Fields
XmlBuffer xmlBuf;
// Public Methods
METHOD write (STRING str) {
this.xmlBuf.append (str: str);
}
METHOD reset () {
this.xmlBuf.clear ();
}
METHOD toString () RETURNS (STRING str) {
str = this.xmlBuf.toString ();
}
}
/*****************************************************************************/
/*
** This class implements a writer for generating and writing XML data to a
** text file.
*/
/*****************************************************************************/
CLASS XmlFileWriter EXTENDS XmlWriter {
// Fields
STRING filename;
// Public Methods
METHOD write (STRING str) {
if (!this.xmlBuf.canAppend (str: str))
this.flush ();
this.xmlBuf.append (str: str);
}
METHOD flush () {
STRING xmlStr = this.xmlBuf.toString ();
xmlStr.Write (filename: this.filename, value: 1, mode: "a");
this.xmlBuf.clear ();
}
}
/*****************************************************************************/
/*
** This class implements a factory for creating an XmlWriter instance.
*/
/* @createStringWriter Creates an XmlStringWriter instance. */
/* @createFileWriter Creates an XmlFileWriter instance. */
/****************************************************************************/
CLASS XmlWriterFactory {
// Public Methods
METHOD createStringWriter (BOOLEAN indent, INTEGER indentSize)
RETURNS (XmlStringWriter writer) {
writer = new (XmlStringWriter);
writer.xmlBuf = XmlBuffer.create (indent: indent,
indentSize: indentSize);
writer.currentState = XmlWriter.startWriterState;
}
METHOD createFileWriter (STRING filename, BOOLEAN indent, INTEGER indentSize)
RETURNS (XmlFileWriter writer) {
writer = new (XmlFileWriter, filename: filename);
writer.xmlBuf = XmlBuffer.create (indent: indent,
indentSize: indentSize);
writer.currentState = XmlWriter.startWriterState;
}
}